<!-- 新增/编辑 员工 -->
<template>
  <div class="page-container">
    <page-form :model="form" layout="vertical" div="true" :rules="rules" ref="formRef">
      <page-form-row>
        <page-form-item field="organizationId" label="所属机构" required>
          <a-tree-select :data="treeData" v-model="form.organizationId" placeholder="请选择" />
        </page-form-item>
        <page-form-item field="realname" label="员工姓名" required>
          <i-input placeholder="请输入" v-model="form.realname" />
        </page-form-item>
        <page-form-item field="phone" label="员工手机号" required>
          <i-input placeholder="请输入" v-model="form.phone" />
        </page-form-item>
        <page-form-item field="staffPost" label="员工岗位" required size="1/3">
          <sysdict-select v-model="form.staffPost" code="staff_post" />
        </page-form-item>
        <page-form-item field="identityCard" label="员工身份证号">
          <i-input placeholder="请输入" v-model="form.identityCard" />
        </page-form-item>
        <page-form-item field="staffType" label="员工类型">
          <sysdict-select v-model="form.staffType" code="staff_type" />
        </page-form-item>
        <page-form-item field="status" label="员工状态" required>
          <a-select placeholder="请选择" v-model="form.status">
            <a-option v-for="(item, index) of staffStatusList" :key="index" :value="item.value" :label="item.name">{{
              item.name
            }}</a-option>
          </a-select>
        </page-form-item>
        <page-form-item field="email" label="员工邮箱">
          <i-input placeholder="请输入" v-model="form.email" />
        </page-form-item>
      </page-form-row>
      <!-- 银行账号 -->
      <BankAccount ref="bankAccountRef" :form="form" />
      <page-form-row>
        <page-form-item field="authOrgIds" label="机构权限" required size="2/3">
          <a-tree-select
            @click="chooseOrg(authList, form.authOrgIds)"
            :data="authList"
            tree-check-strictly
            treeCheckable
            :tree-checked-strategy="'all'"
            v-model="form.authOrgIds"
            multiple
            placeholder="请选择"
            :popup-visible="false"
          />
        </page-form-item>

        <page-form-item field="roleIdList" label="角色" required size="2/3">
          <template #label-extra
            ><a-button type="text" @click="addRole">
              <template #icon>
                <icon-plus-circle />
              </template>
              新增角色</a-button
            ></template
          >
          <fast-transfer style="width: 100%" v-model="form.roleIdList" :selectedList="selectedList" :data-source="roleData" />
        </page-form-item>
      </page-form-row>
      <page-form-row>
        <page-form-item field="username" label="登录名" required size="1/3">
          <a-input-search placeholder="请输入" v-model="form.username" button-text="同手机号" @search="getFindUserInfo" search-button />
        </page-form-item>
        <page-form-item
          field="sea"
          label="登录密码"
          style="position: relative"
          size="1/3"
          labelTooltipContent="密码由8-16位组成，可使用数字、字母、符号，区分大小写"
          :required="pagetype == 'create' ? true : false"
          :rules="[
            { required: pagetype == 'create' ? true : false, message: '请输入登录密码', trigger: 'change' },
            { validator: validatorPwd, trigger: 'change' },
          ]"
        >
          <a-input-search placeholder="请输入" v-model="form.sea" button-text="使用建议密码" search-button @search="getRecommendPwd" />
          <div class="operate-list" style="position: absolute; left: calc(100% + 60px)">
            <a-button class="operate-btn" type="primary" @click="copyAccountPwd">复制登录名和密码</a-button>
          </div>
        </page-form-item>
      </page-form-row>
    </page-form>
  </div>
  <page-form-footer @ok="submitFn" :ok-loading="okLoading" />

  <orgChoose ref="chooseOrgModal" @saveOrgIds="saveOrg" />
  <!-- 创建角色 -->
  <RoleModal ref="roleModal" @ok="createRoleOk" />
</template>

<script setup name="StaffForm">
  import { ref, onMounted } from 'vue'
  import { useRoute } from 'vue-router'
  import { getOrgDetail } from '@/api/organization/organization'
  import { getEpList } from '@/api/merchant/role'
  import useNavigate from '@/hooks/useNavigate'
  import { Message } from '@arco-design/web-vue'
  import { staffPageData, getTree, postandtype, selectAuthList, staffDetail, staffSave } from '@/api/organization/organization'
  import orgChoose from '../form/components/orgchoose.vue'
  import RoleModal from '../../../role/form/role-modal.vue'
  import BankAccount from '@/views/market/components/bank-account.vue'

  const { navigateBack } = useNavigate()
  const route = useRoute()
  const routePrams = route.params
  const staffId = ref()

  const validatorPwd = (value, callback) => {
    if (!value) {
      return
    }
    if (value) {
      if (value.length < 8 || value.length > 16) {
        callback('密码限制8-16位')
      } else {
        if (isPwd(value)) {
          // callback('MIMA');
        } else {
          callback('密码格式不正确')
        }
      }
    }
  }
  const validatorPhone = (value, callback) => {
    if (isPhone(value)) {
      // callback('MIMA');
    } else {
      callback('手机号格式不正确')
    }
  }
  const validatorIdcard = (value, callback) => {
    if (!value) {
      return
    }
    if (isIdcard(value)) {
      // callback('MIMA');
    } else {
      callback('身份证号格式不正确')
    }
  }
  const validatorEmail = (value, callback) => {
    if (!value) {
      return
    }
    if (isEmail(value)) {
      // callback('MIMA');
    } else {
      callback('邮箱格式不正确')
    }
  }

  const rules = {
    organizationId: [{ required: true, message: '请选择所属机构' }],
    realname: [
      { required: true, message: '请输入员工姓名' },
      { maxLength: 20, message: '员工姓名长度不能大于 20 个字符' },
    ],
    phone: [
      { required: true, message: '请输入员工手机号' },
      { validator: validatorPhone, trigger: 'change' },
    ],
    username: [
      { required: true, message: '请输入登录名' },
      { minLength: 4, message: '登录名长度不能小于 4 个字符' },
    ],
    staffPost: [{ required: true, message: '请选择员工岗位' }],
    status: [{ required: true, message: '请选择员工状态' }],
    identityCard: [{ validator: validatorIdcard, trigger: 'change' }],
    email: [{ validator: validatorEmail, trigger: 'change' }],
    authOrgIds: [{ required: true, message: '请选择机构权限' }],
    roleIdList: [{ required: true, message: '请选择角色' }],
  }

  // const visible = ref(true)
  const form = ref({
    organizationId: '',
    realname: '',
    phone: '',
    identityCard: '',
    email: '',
    staffType: '',
    staffPost: '',
    status: '1', //5.6.1默认在职
    authOrgIds: [], //授权的机构ids
    excludeOrgIds: [], //排除的机构ids
    locked: '', //账号状态（0：开启  1：关闭）
    username: '', //登录名（账号状态关闭时不传）
    sea: '', //密码（账号状态关闭时不传）
    roleIdList: [], //角色id集合（账号状态关闭时不传）
    backInfoList: [], // 银行卡列表
  })

  // 弹窗选择机构权限
  const chooseOrgModal = ref(null)
  const chooseOrg = (authList, authOrgIds) => {
    console.log('机构权限选择弹窗')
    chooseOrgModal.value.show(authList, authOrgIds, oldDataTree.value, staffId.value)
  }
  // 弹窗保存权限
  const saveOrg = (ids) => {
    console.log('保存确认机构权限', ids)
    form.value.authOrgIds = ids
  }

  // 编辑 ，添加
  const getRecord = (id) => {
    getTreeData()
    getStaffOption()

    if (id) {
      console.log('需要编辑的员工', id)
      form.value.organizationId = id
      getStaffPageData()
      getSelectAuthList(id) //获取权限列表
      getStaffDetail(id)
    } else {
      getSelectAuthList() //获取权限列表
    }
  }

  // 员工详情
  const getStaffDetail = (id) => {
    staffDetail({ id: id }).then((res) => {
      res.result.organizationId = res.result.organizationId.toString() //所属机构
      res.result.status = res.result.status.toString() //状态
      form.value = res.result
      selectedList.value = []
    })
    staffId.value = id
  }

  // 权限列表
  const authList = ref([])
  const getSelectAuthList = (id) => {
    selectAuthList({ id: id }).then((res) => {
      const authTree = res.result.map((e) => {
        e.key = e.id
        e.title = e.orgName
        e.value = e.id
        e.label = e.orgName
        e.children = [] //创建子级
        return e
      })
      authList.value = setTreeData(authTree)
    })
  }

  // 获取用户名
  const getFindUserInfo = () => {
    form.value.username = form.value.phone
  }

  // 保存
  const okLoading = ref(false)
  const formRef = ref()
  const bankAccountRef = ref()
  const submitFn = (noticeSuccess) => {
    formRef.value.validate(async (error) => {
      if (!error) {
        const validateRes = await bankAccountRef.value.validate()
        if (validateRes == false) return
        okLoading.value = true
        var params = {
          ...form.value,
        }
        staffSave(params)
          .then(() => {
            noticeSuccess()
            navigateBack()
          })
          .finally(() => {
            okLoading.value = false
          })
      }
    })
  }

  // 穿梭框数据(暂无需求 3期实现)

  const existsAccountList = ref([]) //有无后台账号
  const keywordQuery = ref([]) //账号状态
  const limits = ref([]) //数据权限比较符
  const staffStatusList = ref([]) //员工状态
  const getStaffPageData = () => {
    staffPageData().then((res) => {
      existsAccountList.value = res.result.existsAccountList
      keywordQuery.value = res.result.keywordQuery
      limits.value = res.result.limits
      staffStatusList.value = res.result.staffStatusList
    })
  }

  const getRecommendPwd = () => {
    // 密码难度
    let pwdDiff = 1
    let newPwdArr = []
    let pwdLen = 8
    // 难度1
    if (pwdDiff == 1) {
      let randomArr = [3, 4, 1]
      newPwdArr = getStrByGroupIndex(randomArr)
    } else {
      // 难度2
      // 随机生成如 [2, 2, 4] [4, 1, 3] 这样的数组
      let randomArr = getRandomSplitArr(pwdLen)
      let randomStrArr = getStrByGroupIndex(randomArr)
      // 将数组打乱排序
      newPwdArr = randomStrArr.sort(function () {
        return Math.random() - 0.5
      })
    }
    let newPwd = newPwdArr.join('')
    // console.log(newPwd);
    // console.log(form.sea);
    // 兼容极低概率，两次生成重复密码
    if (newPwd == form.value.sea) {
      getRecommendPwd()
    } else {
      form.value.sea = newPwd
      console.log(form.value.sea)

      // this.$forceUpdate()
      // this.$refs.form.clearValidate('sea')
    }
  }

  const getRandomSplitArr = (len) => {
    var num1 = getRandomNumber(len - 2, 1)
    var num2 = getRandomNumber(len - num1 - 1, 1)
    var num3 = len - num1 - num2
    return [num1, num2, num3]
  }

  const getStrByGroupIndex = (randomArr) => {
    // 字母
    var letter = 'ABCDEFGHIJKLMNPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
    // 数字
    var num = '1234567890'.split('')
    // 特殊符号
    var spec = '!~_%&*(),.@#$^'.split('')
    return [...getRandomStr(letter, randomArr[0]), ...getRandomStr(num, randomArr[1]), ...getRandomStr(spec, randomArr[2])]
    function getRandomStr(strArr, len) {
      var maxLen = strArr.length
      var randomStrArr = []
      while (len > 0) {
        let index = getRandomNumber(maxLen, 0)
        randomStrArr.push(strArr[index])
        len--
      }
      return randomStrArr
    }
  }

  // 获取 upper-downer 随机范围内的正整数
  const getRandomNumber = (upper, downer) => {
    return Math.floor(Math.random() * (upper - downer)) + downer
  }

  const isPwd = (s) => {
    return /^(?=.*\d)(?=.*[a-zA-Z])(?=.*[!~_%&*(),.@#$^])[\da-zA-Z!~_%&*/(),.@#$^]{8,16}$/.test(s)
  }

  const isPhone = (s) => {
    return /^1[0-9]{10}$/.test(s)
  }

  const isIdcard = (s) => {
    return /(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|X|x)$)/.test(s)
  }

  const isEmail = (s) => {
    return /^([a-zA-Z0-9])+(([a-zA-Z0-9])|([._-][a-zA-Z0-9])*)+@([a-zA-Z0-9-])+((\.[a-zA-Z0-9-]{2,3}){1,2})$/.test(s)
  }

  const copyAccountPwd = () => {
    let username = form.value.username
    let sea = form.value.sea
    let msg = ''
    // 登录名或密码格式不正确
    if (!username || !sea) {
      msg = '登录名或密码不能为空'
      console.log('登录名或密码不能为空')
      // this.$message.warn(msg, 1)
      Message.warning(msg)
    } else {
      if (form.value.username.length > 4 && isPwd(form.value.sea)) {
        msg = '登录名和密码已复制到剪贴板'
        copyMsg()
      } else {
        msg = '登录名或密码格式不正确'
      }
      Message.warning(msg)
    }
  }

  const copyMsg = () => {
    // Implement your copy logic here
    const msg = `PC端操作平台：${location.origin}\r\n登录名：${form.value.username}\r\n密码：${form.value.sea}`
    try {
      // 传统 document.execCommand 方法 MDN 已废弃
      const save = function (e) {
        e.clipboardData.setData('text/plain', msg)
        e.preventDefault()
      }
      document.addEventListener('copy', save, { once: true })
      document.execCommand('copy')
    } catch (e) {
      // 新标准 注意此处是异步的
      const item = new window.ClipboardItem({
        'text/plain': new Blob([msg], { type: 'text/plain' }),
      })
      navigator.clipboard.write([item]).then(
        function () {
          console.log('Async: Copying to clipboard was successful!')
        },
        function (err) {
          console.error('Async: Could not copy text: ', err)
        }
      )
    }
  }

  const oldDataTree = ref([]) //未处理的树
  // 树 数据
  const treeData = ref([])
  const getTreeData = () => {
    const param = {
      checkedId: '',
      isChecked: 'false',
      isOpen: 'true',
    }
    getTree(param).then((res) => {
      oldDataTree.value = res.result
      const orgTree = res.result.map((e) => {
        e.key = e.id.toString()
        e.value = e.id
        e.title = e.name
        e.children = [] //创建子级
        return e
      })

      treeData.value = setTreeData(orgTree)
    })
  }

  // 表结构转化为树结构
  const setTreeData = (arr) => {
    // 删除所有的children,以防止多次调用
    arr.forEach(function (item) {
      delete item.children
    })
    let map = {} //构建map
    arr.forEach((i) => {
      map[i.id] = i //构建以id为键 当前数据为值
    })
    let treeData = []
    arr.forEach((child) => {
      const mapItem = map[child.parentId] //判断当前数据的parentId是否存在map中
      if (mapItem) {
        //存在则表示当前数据不是最顶层的数据
        //注意： 这里的map中的数据是引用了arr的它的指向还是arr,当mapItem改变时arr也会改变，踩坑点
        ;(mapItem.children || (mapItem.children = [])).push(child) //这里判断mapItem中是否存在child
      } else {
        //不存在则是顶层数据
        child.top = true
        treeData.push(child)
      }
    })
    console.log(treeData)
    return treeData
  }

  const staffPosts = ref([])
  const staffTypes = ref([])
  const getStaffOption = () => {
    postandtype({ codeList: ['staff_type', 'staff_post'] }).then((res) => {
      staffPosts.value = res.result.staff_post
      staffTypes.value = res.result.staff_type
    })
  }

  const saveSub = (res) => {
    console.log('确认,更新下拉框数据', res)
    getStaffOption()
  }

  //机构详情(新增时默认机构权限)
  const orgDetail = (id) => {
    getOrgDetail({ id: id }).then((res) => {
      form.value.authOrgIds = res.result.authOrgIds
    })
  }

  // 角色
  const roleData = ref([])
  const selectedList = ref([])
  const getRoleData = () => {
    getEpList({
      available: 1,
    }).then((res) => {
      roleData.value = res.result.map((item) => {
        return {
          label: item.role,
          value: item.id,
        }
      })
    })
  }
  // 创建角色
  const roleModal = ref()
  const addRole = () => {
    roleModal.value.open()
  }
  // 创建角色ok
  const createRoleOk = () => {
    getRoleData()
  }

  // mounted 调用接口
  const pagetype = ref('create')
  onMounted(() => {
    const id = routePrams.id
    const organizationId = routePrams.organizationId
    if (id) {
      getRecord(id)
      pagetype.value = 'edit'
    }
    if (organizationId) {
      form.value.organizationId = organizationId
      orgDetail(form.value.organizationId)
      getRecord()
    }
    getRoleData()
    getStaffPageData()
  })

  defineExpose({
    getRecord,
    saveSub,
  })
</script>

<style scoped>
  .operate-list {
    position: absolute;
    margin-left: -40px;
  }
  .operate-btn + .operate-btn {
    margin-left: 16px;
  }
  /* .footer-operater {
    width: 100%;
    height: 60px;
    padding: 0 20px;
    box-shadow: 0px -3px 12px 0px rgba(0,0,0,0.1);
    background-color: var(--color-white);
  }  */
</style>
